
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include "../usb_monitor.h"
#include "../../log/log.h"

using namespace std;
using namespace dmcg::module::libusb;

bool work = true;
boost::mutex io_mutex;
boost::asio::io_service s;
std::vector<usb_device> connect_devices;

void handle_stop();
void discon_devices(UsbMonitor *);
int usb_device_notify(const std::string &act, const std::vector<usb_device> &devices);

int main()
{
  dmcg::module::log::init("usb_monitor_tests");

  cout << "begin..." << endl;
  auto um = new UsbMonitor();

  new boost::thread(boost::ref(*um));

  um->UsbDeviceAction.connect(
      [](const std::string &act, const std::vector<usb_device> &devices) -> int32_t {
        return usb_device_notify(act, devices);
      });

  new boost::thread(boost::bind(&discon_devices, um));

  boost::asio::signal_set signals(s);

  signals.add(SIGINT);
  signals.add(SIGTERM);
#if defined(SIGQUIT)
  signals.add(SIGQUIT);
#endif

  signals.async_wait(boost::bind(&handle_stop));

  s.run();

  cout << "exit..." << endl;

  return 0;
}

void handle_stop()
{
  work = false;
  s.stop();
}

int usb_device_notify(const std::string &act, const std::vector<usb_device> &devices)
{
  cout << "action: " << act << endl;

  for (auto ud : devices)
  {
    cout << "idVendor: " << ud.idVendor << endl;
    cout << "idProduct: " << ud.idProduct << endl;
    cout << "serial: " << ud.serial << endl;
    cout << "manufacturer: " << ud.manufacturer << endl;
    cout << "product: " << ud.product << endl;
    cout << "name: " << ud.name << endl;

    boost::mutex::scoped_lock lock(io_mutex);
    connect_devices.push_back(ud);
  }

  return 0;
}

void discon_devices(UsbMonitor *um)
{
  // sleep(15);
  // um->remove_all_device;

  // return;

  while (work)
  {
    sleep(15);

    boost::mutex::scoped_lock lock(io_mutex);
    std::vector<usb_device>::iterator itr = connect_devices.begin();
    if (itr != connect_devices.end())
    {
      um->remove_device(*itr);
      itr = connect_devices.erase(itr);
    }
  }
}
